//基于数组实现队列
interface queue<T>{
    //队列放的值
    [index: number]: T;
    //队列的长度
    length: number;
    //入列
    enqueue(ele: T): T;
    //出列
    dequeue(): T;
    //获取前端元素
    beforeQueue(): T
    //获取后端元素
    laterQueue(): T
    //将数据转成字符串
    toString(): string
}

class Queue<T> implements queue<T>{
    [index: number]: T;
    length: number = 0;
    constructor(...ele: T[]) {
        for (let index = 0; index < ele.length; index++) {
            this[index] = ele[index]
            this.length++
        }
    }

    enqueue(ele: T): T{
        return this[this.length++] = ele
    }

    dequeue(): T{
        const old: T = this[0]
        for (let index = 0; index < this.length;index++){
            this[index]=this[index+1]
        }
        delete this[this.length - 1]
        this.length--
        return old
    }

    beforeQueue(): T{
        return this[0]
    }

    laterQueue(): T{
        return this[this.length-1]
    }

    toString(): string {
        let str: string = ""
        for (let index = 0; index < this.length; index++) {
            str += this[index]
        }
        return str
    }

    protected splice(ele: T, i: number):number {
        this.length++;
        for (let index = this.length - 1; index > i;index--){
            this[index]=this[index-1]
        }
        this[i] = ele
        return this.length
    }
}

//约束优先队列传递的数据
interface element<T>{
    value: T;//元素值
    rank: number//优先级别
}
//优先级队列
class priorityQueue<T> extends Queue<element<T>>{
    constructor(...ele: Array<element<T>>) {
        super()
        this[this.length++] = ele[0]
        for (let index = 1; index < ele.length;index++){
            this.priorityInsert(ele[index])
        }
    }
    priorityInsert(ele:element<T>):number {
        if (this.length>0) {
            for (let index = this.length - 1; index >= 0; index--){
                if (this[index].rank >= ele.rank) {
                    this.splice(ele, index + 1)
                    return
                }
            }
            this.splice(ele, 0)
        } else {
            this[this.length++] = ele
        }
        return this.length
    }
}

export {
    Queue,
    priorityQueue
}
